/*
 * Copyright (C) 2009 Chang Min Lee <ch5ngmn@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details. (/COPYING)
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include "SvrCommBroker.h"
#include "ace/Log_Msg.h"
#include "ace/ARGV.h"
#include "ace/Get_Opt.h"

SvrCommBroker::SvrCommBroker(ACE_UINT32 maxSession, 
																								 long evictSec,
																								 IoEventHandler *handler)
: maxSession_ (maxSession),
  evictTimeout_(evictSec, 0),
	adminServerCreator_(0),
	sessionServerCreator_(0),
	sessionManager_(0),
  handler_ (handler)
{
}

SvrCommBroker::~SvrCommBroker()
{
	CORBA::Object_var object = orb_->resolve_initial_references ("RootPOA");

	PortableServer::POA_var root_poa = PortableServer::POA::_narrow (object.in ());
	ACE_ASSERT (PortableServer::POA::_nil() != root_poa);

	root_poa->the_POAManager ()->deactivate (1, 1);
}

int
SvrCommBroker::open (int argc, ACE_TCHAR* argv [])
{
	if (0 == CommBroker::open (argc, argv))
	{
		CORBA::Object_var object = orb_->resolve_initial_references ("RootPOA");

		PortableServer::POA_var root_poa = PortableServer::POA::_narrow (object.in ());
		ACE_ASSERT (PortableServer::POA::_nil() != root_poa);

		root_poa->the_POAManager()->activate ();

		IoSessionManager *sessionManager=0;
		ACE_NEW_RETURN (sessionManager, IoSessionManager (handler_, maxSession_), -1);
		sessionManager_.reset (sessionManager);

		sessionManager_->load ();

		IoSessionAdminServerCreator *adminServerCreator=0;
		ACE_NEW_RETURN (adminServerCreator, IoSessionAdminServerCreator(sessionManager), -1);
		adminServerCreator_.reset (adminServerCreator);

		IoSessionServerCreator *sessionServerCreator=0;
		ACE_NEW_RETURN (sessionServerCreator, 
			IoSessionServerCreator(maxSession_, evictTimeout_, sessionManager), -1);
		sessionServerCreator_.reset (sessionServerCreator);

		sessionServerCreator_->orb(orb_.in());
		sessionServerCreator_->open (argc, argv);
		sessionServerCreator_->activate_poa (root_poa.in());
		sessionServerCreator_->activate_server (naming_.in());

		adminServerCreator_->orb(orb_.in());
		adminServerCreator_->open (argc, argv);
		adminServerCreator_->activate_poa (root_poa.in());
		adminServerCreator_->activate_server (naming_.in());
		
		return 0;
	}

	return -1;
}

void
SvrCommBroker::close (bool wait_for_completion)
{
	if (!adminServerCreator_.null())
		adminServerCreator_->close();

	if (!sessionServerCreator_.null())
		sessionServerCreator_->close();

	CommBroker::close (wait_for_completion);

	sessionManager_->unload ();
}

void 
SvrCommBroker::send (ACE_UINT32 key, const ACE_UINT8 *data, ACE_UINT32 length)
{
	if (!sessionManager_.null())
		sessionManager_->send (key, data, length);
}